{-# LANGUAGE RecordWildCards #-} 

module Main where

import Data.List
import Data.Tree

import Graphics.Vty
import Graphics.Vty.Widgets.All

import qualified Tree as T
import qualified EditBox as E


main = do
  vty <- mkVty
  mainLoop vty $ UiState testTree E.empty ""
  shutdown vty


testTree = T.defaultTree
  [ Node "a" [Node n [] | n <- ["aa", "ab", "ac", "ad"]]
  , Node "b" []
  , Node "c"
    [ Node "ca" [Node n [] | n <- ["caa", "cab", "cac"]]
    , Node "cb" [Node "cba" []]
    , Node "cc" [Node n [] | n <- ["cca", "ccb", "ccc"]]
    , Node "cd" []
    ]
  , Node "d" [Node "da" []]
  ]

data UiState
  = UiState
    { rosterTree :: T.Tree String
    , cmdLine :: E.EditBox
    , bufferText :: String
    }

mkUi (UiState {..})
  = text (def_attr `with_back_color` blue) "header"
  <--> (rosterTree
    <++> vBorder def_attr
    <++> wrappedText def_attr bufferText)
  <--> text (def_attr `with_back_color` blue) "info"
  <--> cmdLine


resizeAll (UiState {..}) w h
  = UiState (T.resize w h rosterTree) (E.resize w h cmdLine) bufferText 


mainLoop vty st@(UiState {..}) = do
  mkImage vty (mkUi st) >>= update vty . pic_for_image
  ev <- next_event vty
  case ev of
    -- TODO: заюзать Data.Accessor для обновления полей
    EvKey (KASCII 'p') [MCtrl]  -> mainLoop vty $ st { rosterTree = T.moveUp   rosterTree }
    EvKey (KASCII 'n') [MCtrl]  -> mainLoop vty $ st { rosterTree = T.moveDn   rosterTree }
    EvKey (KASCII 'b') [MCtrl]  -> mainLoop vty $ st { rosterTree = T.collapse rosterTree }
    EvKey (KASCII 'f') [MCtrl]  -> mainLoop vty $ st { rosterTree = T.expand   rosterTree }
    EvKey (KASCII 'q') [MCtrl]  -> return ()

    EvKey (KASCII  c ) []       -> mainLoop vty $ st { cmdLine = E.insert c cmdLine }
    EvKey KLeft        []       -> mainLoop vty $ st { cmdLine = E.moveLeft cmdLine }
    EvKey KRight       []       -> mainLoop vty $ st { cmdLine = E.moveRight cmdLine }
    EvKey KHome        []       -> mainLoop vty $ st { cmdLine = E.moveToHome cmdLine }
    EvKey KEnd         []       -> mainLoop vty $ st { cmdLine = E.moveToEnd cmdLine }

    EvKey KBS          []       -> mainLoop vty $ st { cmdLine = E.backSpace cmdLine }
    EvKey KDel         []       -> mainLoop vty $ st { cmdLine = E.delete cmdLine }
--    EvKey KEnter     [MShift] -> mainLoop vty $ st { cmdLine = E.insert '\n' cmdLine } -- FIXME: почему-то не работает MShift
    EvKey KEnter       []
      -> mainLoop vty $ st
        { cmdLine = E.empty
        , bufferText = bufferText ++ "\n" ++ (E.contents cmdLine)
        }

    EvResize w h                -> mainLoop vty $ resizeAll st w h
    _                           -> mainLoop vty st
  


{- emacs
C-a, C-e, C-/, C-k, C-y, M- y
C-v, M-v
C-spc, C-w
-}
